import DrawerFooter from '@/components/DrawerFooter';
import MapModal from '@/components/MapModal';
import { useService, useStore } from '@/hooks';
import { Button, Dialog, Form, Input, Message, Table, Divider } from '@alifd/next';
import { t } from '@lingui/macro';
import { observable, toJS } from 'mobx';
import { observer } from 'mobx-react-lite';
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { FieldsGrid } from '../stores/definitions';
import AttachmentPanel from './AttachmentPanel';
import ChargeForm from './ChargeForm';
import styles from './StationForm.module.scss';
import { arrTransferStr, deconstructionMapObj } from '@/utils/util';

const FromItem = Form.Item;

const StationForm = ({ stationId, modal, onSubmit, onCancel }) => {
  const { scStationStore: store } = useStore();
  const [isViewMode] = useState(modal[0] === 'view');
  const formProps = isViewMode ? { field: false } : {};
  const formField = useRef(); // 用于保存通过saveField获取到的field实例
  const [station] = useState(() => observable({}));
  const editCtx = useRef({ origin: {}, changed: {} }).current; // 用于计算是否修改
  const { apiLbs } = useService();
  const [map, setMap] = useState({ show: false, coord: '', cityName: '' });
  const [rsMap, setRsMap] = useState({ show: false, coord: '', cityName: '' });
  const [idx, setIdx] = useState();
  const [opCompanys, setOPCompanys] = useState([]);
  const [curCharge, setCurCharge] = useState();

  const columns = [
    {
      title: t`序号`,
      dataIndex: 'id',
      align: 'center',
      cell: (v, i) => <span>{i + 1}</span>,
    },
    {
      title: t`公司名称`,
      dataIndex: 'companyId',
      width: 160,
      align: 'center',
      cell: (v) => store.operatingCompanys.find((p) => p.value === v)?.label,
    },
    {
      title: t`站点Id`,
      dataIndex: 'stationId',
      width: 160,
      align: 'center',
      cell: (v) => store.stationSet.find((p) => p.value === v)?.label || '无',
    },
    {
      title: t`经纬度`,
      dataIndex: 'longLat',
      width: 160,
      align: 'center',
    },
    {
      title: t`链接`,
      dataIndex: 'link',
      width: 200,
      align: 'center',
    },
    {
      title: t`班次提示内容`,
      dataIndex: 'prompt',
      width: 200,
      align: 'center',
    },
    {
      title: t`详细地址`,
      dataIndex: 'address',
      width: 200,
      align: 'center',
    },
    {
      title: t`操作`,
      dataIndex: 'name',
      align: 'center',
      cell: (v, i, r) => (
        <>
          <Button type="primary" text onClick={() => handleCurCharge(r)}>{t`编辑`}</Button>
          <Divider direction="ver" />
          <Button type="primary" text style={{ color: 'red' }} onClick={() => handleDeleteState(i)}>{t`删除`}</Button>
        </>
      ),
    },
  ];


  // 重载definitions中的定义，处理一些根据上下文的动态定义
  const overrideModel = {
    siteMapping: {
      ui: {
        renderer: () => (
          <>
            {!isViewMode && <Button type="primary" style={{ marginBottom: 10 }} onClick={() => handleAddState()}>{t`添加运营公司`}</Button>}
            <Table
              hasBorder={false}
              dataSource={opCompanys}
              columns={columns}
              className={styles.discountInfos_table}
              onRowClick={(_, index) => setIdx(index)}
            />
          </>
        ),
        span: 4,
      },
    },
    longLat: {
      ui: {
        renderer: (v) => (<Input
          value={v}
          placeholder={t`选择经纬度`}
          addonAfter={isViewMode ? null : <Button type="primary" onClick={() => handleMapOpen(v, 'pt')}>{t`获取经纬度`}</Button>}
        />),
        itemProps: { required: true },
      },
    },
    rsLongLat: {
      ui: {
        renderer: (v) => (<Input
          value={v}
          placeholder={t`选择经纬度`}
          addonAfter={isViewMode ? null : <Button type="primary" onClick={() => handleMapOpen(v, 'rs')}>{t`获取经纬度`}</Button>}
        />),
      },
    },
    link: {
      ui: {
        renderer: (v) => {
          return (
            <Input.TextArea
              value={v}
              placeholder={t`请输入详情地址链接`}
            />
          );
        },
      },
    },
    rsLink: {
      ui: {
        renderer: (v) => {
          return (
            <Input.TextArea
              value={v}
              placeholder={t`请输入拼车详情地址链接`}
            />
          );
        },
      },
    },
  };

  useEffect(() => { if (modal[1]?.startsWith?.('toClose')) handleCancel(); }, [modal]);

  useEffect(() => {
    (async () => {
      await store.getCompany();
      await store.searchStation();
      await store.allRegions(2);
      if (stationId) {
        const data = await store.get(stationId);
        editCtx.origin = _.cloneDeep(data);
        _.assign(station, { ...data, disable: !data.disable });
        const { siteMapping } = station;
        if (siteMapping) {
          const outputSitMapping = Object.keys(siteMapping).map((companyId) => ({
            companyId,
            ...siteMapping[companyId],
          }));
          setOPCompanys(outputSitMapping);
        }
      } else {
        // 添加操作
        _.set(station, 'city', store.region.itemId);
      }
    })();
  }, []);

  const handleAddState = useCallback(() => {
    const data = {
      id: new Date().getTime(),
      companyId: 'platform',
      stationId: '无',
      longLat: '无',
      link: '无',
      address: '无',
    };
    setOPCompanys((pre) => {
      const cloneData = [...pre];
      cloneData.push(data);
      return cloneData;
    });
  }, [setOPCompanys]);

  const handleDeleteState = useCallback((i) => {
    setOPCompanys((pre) => {
      const arr = [...pre];
      arr.splice(i, 1);
      return arr;
    });
  }, [setOPCompanys]);

  const handleCurCharge = useCallback((values) => {
    setCurCharge(values);
  }, [setCurCharge]);

  if (!station) return <></>;

  const handleChange = (values, item) => {
    const { name, value } = item;
    _.set(station, name, value);
    // 联动效果可以在这里通过设置station属性实现

    // eslint-disable-next-line eqeqeq
    editCtx.changed[name] = value == _.get(editCtx.origin, name) ? undefined : value;
  };

  const handleMapOpen = async (v, type) => {
    const { cityText, name, city: _city } = toJS(station);
    if (!_city) {
      Message.warning(t`请先选择城市`);
      return;
    }
    if (!v && !station.name) {
      Message.warning(t`请先设置名称`);
      return;
    }
    let coord = v;
    let currentCity = modal[0] === 'add' ? store._city[_city] : cityText;
    if (!v) {
      const r = await apiLbs.placeSearch({ region: currentCity, keyword: name });
      const { location, city, province } = r[0] || {};
      currentCity = city || province;
      coord = arrTransferStr(location);
    }
    if (type === 'pt') {
      setMap({ show: true, coord, cityName: currentCity });
    } else {
      setRsMap({ show: true, coord, cityName: currentCity });
    }
  };

  const handleCoordPicked = async (coord) => {
    const location = deconstructionMapObj(toJS(coord));
    _.set(station, 'longLat', location);
    formField.current.reset(['longLat']);
    setMap({ show: false });
  };

  const handleRsCoordPicked = async (coord) => {
    const location = deconstructionMapObj(toJS(coord));
    _.set(station, 'rsLongLat', location);
    formField.current.reset(['rsLongLat']);
    setRsMap({ show: false });
  };

  const handleCancel = () => {
    // eslint-disable-next-line no-param-reassign
    if (!_.isEmpty(_.transform(editCtx.changed, (r, v, k) => { v !== undefined && (r[k] = v); }))) {
      Dialog.confirm({
        content: t`放弃修改内容？`,
        onOk: () => onCancel?.(),
      });
      return;
    }
    onCancel?.();
  };

  const handleSubmit = (value, errors, _field) => {
    if (!_.isEmpty(errors)) {
      return;
    }
    if (hasDuplicateIds(opCompanys)) {
      return Dialog.confirm({
        content: t`运营公司不可重复设置!`,
      });
    }
    const siteMapping = opCompanys.reduce((acc, item) => {
      const { companyId, stationId: id, longLat, link, address, cityId, prompt } = item;
      const key = companyId;
      acc[key] = {
        stationId: id || '',
        longLat: longLat || '',
        link: link || '',
        address: address || '',
        cityId,
        prompt: prompt || '',
      };
      return acc;
    }, {});
    station.siteMapping = siteMapping;
    _.set(station, 'disable', !station.disable);
    onSubmit?.(station);
  };

  const chargeOnSubmit = (values, errors) => {
    if (errors) {
      return;
    }
    setOPCompanys((pre) => {
      const newCharge = [...pre];
      newCharge[idx] = values;
      return newCharge;
    });
    setCurCharge(false);
  };

  /**
   * 校验是否存在重复公司
   * @param {*} array
   * @returns true
   */
  function hasDuplicateIds(array) {
    return new Set(array.map((item) => item.companyId)).size !== array.length;
  }

  return (
    <Form
      isPreview={isViewMode}
      {...formProps}
      value={station}
      inline
      onChange={handleChange}
      useLabelForErrorMessage
      saveField={(f) => { formField.current = f; }}
    >
      <FieldsGrid
        formData={station}
        overrideModel={overrideModel}
        mode={modal[0]}
        columns={4}
        fields={[
          'city', 'areaName', 'name', 'address', 'longLat', 'rsAddress', 'rsLongLat',
          'disable', 'types']}
      />
      <FieldsGrid
        formData={station}
        overrideModel={overrideModel}
        mode={modal[0]}
        columns={4}
        fields={[
          'link', 'rsLink', 'description', 'siteMapping']}
      />

      <AttachmentPanel station={station} mode={modal[0]} />

      <DrawerFooter>
        <FromItem>
          {!isViewMode && <Form.Submit validate type="primary" onClick={handleSubmit}>{t`保存`}</Form.Submit>}
          <Button style={{ marginLeft: 8 }} onClick={handleCancel}>{t`取消`}</Button>
        </FromItem>
      </DrawerFooter>
      <MapModal
        visible={map.show}
        coord={map.coord}
        cityName={map.cityName}
        containerId={'scStationLocation'}
        onClose={() => setMap({ show: false })}
        onCancel={() => setMap({ show: false })}
        onPick={handleCoordPicked}
      />
      <MapModal
        visible={rsMap.show}
        coord={rsMap.coord}
        cityName={map.cityName}
        containerId={'rcStationLocation'}
        onClose={() => setRsMap({ show: false })}
        onCancel={() => setRsMap({ show: false })}
        onPick={handleRsCoordPicked}
      />
      <Dialog
        visible={!!curCharge}
        onCancel={() => setCurCharge(false)}
        onClose={() => setCurCharge(false)}
        title={t`编辑内容`}
        style={{ width: '30%' }}
        footer={null}
      >
        <ChargeForm
          data={curCharge}
          stationInfo={station}
          onSubmit={(r, errors) => chargeOnSubmit(r, errors)}
          onCancel={() => setCurCharge(false)}
        />
      </Dialog>
    </Form>
  );
};

export default observer(StationForm);
